/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package redes;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Thiago
 */
public class Roteador extends Thread {

    Servidor server;

    List<Link> links;

    int minhaLinha = 0;

    int id;

    int matriz[][];

    String envio = "";

    public Roteador(int id) {
        this.id = id;
        this.links = new ArrayList<>();
        this.links.add(new Link(this, 0, 0, this, 0, 0, 0));
        this.server = new Servidor(this);
    }

    public void montarMsg() {
        envio = String.valueOf(this.minhaLinha) + "|";
        for (int j = 1; j < matriz.length; j++) {
            envio += j;
            envio += "|";
            envio += matriz[minhaLinha][j];
            envio += "|";
        }
        envio = envio.substring(0, envio.length() - 1);
        envio += ".";
//        System.out.println(envio);
    }

    public void receberMsg(String msg) {
        msg = msg.substring(0, msg.indexOf("."));
//        System.out.println(msg);
        String[] strArray = msg.split("\\|");
        int[] intArray = new int[strArray.length];
        for (int i = 0; i < strArray.length; i++) {
            intArray[i] = Integer.parseInt(strArray[i]);
        }
        
        int linha = intArray[0];
        
        for (int i = 1; i < intArray.length; i++) {
            matriz[linha][intArray[i]] = intArray[i+1];
            i++;
        }

//        for (int i = 3; i < intArray.length; i++) {
//            int ii = intArray[i];
//            i++;
//            int jj = intArray[i];
//            i++;
//            int dist = intArray[i];
//            if(matriz[ii][jj] > dist){
//                matriz[ii][jj] = dist;
//            }
//        }
    }

    public int[][] montarTabela(View v) {

        matriz = new int[v.getRoteadores().size() + 1][v.getRoteadores().size() + 1];

        for (int i = 0; i < matriz.length; i++) {
            for (int j = 0; j < matriz.length; j++) {
                matriz[i][j] = 99;
            }
        }

        matriz[0][0] = this.id;

        for (int i = 1; i <= v.getRoteadores().size(); i++) {
            matriz[0][i] = v.getRoteadores().get(i - 1).getIdRoteador();
        }

        for (int i = 1; i <= v.getRoteadores().size(); i++) {
            matriz[i][0] = v.getRoteadores().get(i - 1).getIdRoteador();
        }

        for (int i = 1; i < matriz.length; i++) {
            if (matriz[i][0] == this.id) {
                minhaLinha = i;
                break;
            }
        }

        for (int i = 1; i < matriz.length; i++) {
            int vizinho = matriz[0][i];
            for (int j = 0; j < this.links.size(); j++) {
                if (this.links.get(j).getR2().getIdRoteador() == vizinho) {
                    matriz[minhaLinha][i] = this.links.get(j).getDistancia();
                    break;
                }
            }
        }
        return matriz;
    }

    public int getIdRoteador() {
        return id;
    }

    public List<Link> getLinks() {
        return links;
    }

    public void newLink(Roteador r1, int ip1, int mascara1, Roteador r2, int ip2, int mascara2, int distancia) {
        if (r1.getIdRoteador() == this.id) {
            this.links.add(new Link(r1, ip1, mascara1, r2, ip2, mascara2, distancia));
        } else {
            this.links.add(new Link(r2, ip2, mascara2, r1, ip1, mascara1, distancia));
        }
    }

    @Override
    public void run() {
        server.start();
        montarMsg();
        try {
            cliente();
        } catch (IOException ex) {
            Logger.getLogger(Roteador.class.getName()).log(Level.SEVERE, null, ex);
        }
        while(true){
            menorCaminho();
            montarMsg();
            try {
                cliente();
            } catch (IOException ex) {
                Logger.getLogger(Roteador.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public void cliente() throws SocketException, IOException {
        for (int i = 0; i < links.size(); i++) {
            int PORTA = (int) (8000 + links.get(i).getR2().getIdRoteador());
            //Socket UDP
            DatagramSocket socketUDP = new DatagramSocket();
            InetAddress IPServidor = InetAddress.getByName("127.0.0.1");

            byte[] msgEnvio = envio.getBytes();

            //datagrama UDP (pacote) de envio
            DatagramPacket datagrama = new DatagramPacket(msgEnvio, msgEnvio.length, IPServidor, PORTA);

            socketUDP.send(datagrama);

            socketUDP.close();
//            System.out.println("Socket Fechado.");
        }
    }
    
    public void menorCaminho(){
        int x, y;
        int l = this.minhaLinha;
        for (int j = 1; j < matriz.length; j++) {
            for (int n = 1; n < matriz.length; n++) {
                if(l != n){
                    x = matriz[l][j];
                    if(matriz[n][j] < x){
                        y = matriz[n][j]+matriz[l][n];
                        if(y < x){
                            System.out.println("troca");
                            matriz[l][j] = y;
                        }
                    }
                }
            }
        }
    }

    public int[][] getMatriz() {
        return matriz;
    }
}
